﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint.WebControls;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace SPHealth.SharePoint.dbSize.Layouts.SPHealth.SharePoint.dbSize
{

    public partial class ListDatabaseSizes : LayoutsPageBase
    {

        protected DataTable PropertyCollection = new DataTable();

        protected void Page_Load(object sender, EventArgs e)
        {
            #region Modal Script
            // creates the required javascript to open a modal dialog
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("<script language='javascript' type='text/javascript'>");
            sb.AppendLine("function showDatabaseSizeDetails(databaseName, databaseID) { ");
            sb.AppendLine("var options = { ");
            sb.AppendLine("url: '/_admin/sphealth/DatabaseSizeDetails.aspx?id=' + databaseID, ");
            sb.AppendLine("width: 710, ");
            sb.AppendLine("height: 440, ");
            sb.AppendLine("title: 'Database Size - ' + databaseName, ");
            sb.AppendLine("allowMaximize: false, ");
            sb.AppendLine("showClose: true ");
            sb.AppendLine("};");
            sb.AppendLine("SP.UI.ModalDialog.showModalDialog(options); ");
            sb.AppendLine("}");
            sb.AppendLine("</script>");
            Literal modalScript = new Literal();
            modalScript.Text = sb.ToString();
            this.Controls.Add(modalScript);
            #endregion

            // setup
            int dbCounter = 0;
            bool oddrow = false;
            PropertyCollectionBinder pcb = new PropertyCollectionBinder();

            #region Get our list of database
            SortedList<string, SPContentDatabase> dbList = new SortedList<string, SPContentDatabase>();
            foreach (SPWebApplication webApplication in SPWebService.ContentService.WebApplications)
            {
                if (webApplication.Status == SPObjectStatus.Online)
                {
                    // get a list of the content databases in the farm
                    foreach (SPContentDatabase contentDatabase in webApplication.ContentDatabases)
                    {
                        dbList.Add(contentDatabase.Name, contentDatabase);
                    }
                }
            }
            #endregion

            #region Add databases to grid view
            foreach (SPContentDatabase contentDatabase in dbList.Values)
            {
                try
                {
                    // build the required output for the gridview
                    string dbLink = string.Format(BuildLinkScript(contentDatabase), contentDatabase.Name);
                    string dbSpark = string.Format(BuildLinkScript(contentDatabase), BuildSparkScript(contentDatabase, dbCounter, oddrow, true));
                    string logSpark = string.Format(BuildLinkScript(contentDatabase), BuildSparkScript(contentDatabase, dbCounter, oddrow, false));

                    // increment our counters and alternating colors
                    dbCounter++;
                    oddrow = !oddrow;

                    // add our row to the gridview
                    pcb.AddProperty(dbLink, dbSpark, logSpark);
                }
                catch (Exception ex)
                {
                    /* best endevours */
                }
            }

            pcb.BindGrid(grdDBsizes);
            #endregion
        }

        /// <summary>
        ///  Creates a hyperlink that will throw a modal dialog
        /// </summary>
        /// <param name="contentDatabase">The SPContentDatabase that is used to contruct the hyperlink</param>
        /// <returns>A string that contains a hyperlink markup</returns>
        private static string BuildLinkScript(SPContentDatabase contentDatabase)
        {
            return "<A href=\"javascript:showDatabaseSizeDetails('" + contentDatabase.Name + "','" + contentDatabase.Id.ToString() + "')\" target=\"_self\">{0}</A>";
        }

        private static string BuildSparkScript(SPContentDatabase contentDatabase, int dbCounter, bool oddrow, bool showData)
        {
            // setup
            string sparkPrefix = "dataSpark";
            if (!showData)
                sparkPrefix = "logSpark";

            string sparkValues = GetDatabaseSparkSizes(contentDatabase, showData);

            // create the required javascript to render a spark line
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("<div id='" + sparkPrefix + dbCounter.ToString() + "' style='width:200px; height:45px;'></div>");
            sb.AppendLine("<script type='text/javascript' language='javascript'>");
            sb.AppendLine("    $(document).ready(function () {");
            sb.AppendLine("        var line1 = [" + sparkValues + "];");
            sb.AppendLine("        var plot1 = $.jqplot('" + sparkPrefix + dbCounter.ToString() + "', [line1], {");
            sb.AppendLine("            grid: { borderColor: '" + (oddrow ? "#F2F9FC" : "#ffffff") + "', background: '" + (oddrow ? "#F2F9FC" : "#ffffff") + "', shadow: false },");
            sb.AppendLine("            seriesDefaults: { showMarker: false" + (!showData ? "" : ", color: '#EAA228'") + " },");
            sb.AppendLine("            legend: { show: false },");
            sb.AppendLine("            axesDefaults: { show: false, pad: 0 },");
            sb.AppendLine("            axes: { xaxis: { showTicks: false, drawMajorGridlines: false, drawMinorGridlines: false, drawMinorGridlines: false, drawMajorTickMarks: false }, yaxis: { showTicks: false, drawMajorGridlines: false, drawMinorGridlines: false, drawMinorGridlines: false, drawMajorTickMarks: false } }");
            sb.AppendLine("        });");
            sb.AppendLine("    });");
            sb.AppendLine("</script>");
            return sb.ToString();
        }

        private static string GetDatabaseSparkSizes(SPContentDatabase contentDatabase, bool showData)
        {
            string key = "SPHealth.DBSizeHistory";
            if (!showData)
                key = "SPHealth.LogSizeHistory";


            // the raw data will be a comma seperated string in date,size,date,size,date,size format
            StringBuilder sparkValues = new StringBuilder();
            if (contentDatabase.Properties.ContainsKey(key))
            {
                string rawData = contentDatabase.Properties[key].ToString();
                if (!string.IsNullOrEmpty(rawData))
                {
                    string[] parts = rawData.Split(new char[] { ',' });
                    if (parts.Length > 1)
                    {
                        // take every alternate value (size)
                        for (int x = 1; x <= parts.Length; x = x + 2)
                        {
                            sparkValues.Append(parts[x]);
                            if (x < parts.Length - 2)
                                sparkValues.Append(",");
                        }
                    }
                }
                else
                {
                    // no data found
                    sparkValues.Append("0,0,0");
                }
            }
            else
            {
                // no data found
                sparkValues.Append("0,0,0");
            }

            return sparkValues.ToString();
        }

        public class mySPfield : SPBoundField
        {
            protected override void ChildControlDataBinding(System.Web.UI.Control childControl, object dataItem, System.ComponentModel.MemberDescriptor dataFieldPropertyDescriptor)
            {
                PlaceHolder placeHolder = (PlaceHolder)childControl;
                string propertyVal = GetPropertyValue(dataItem, dataFieldPropertyDescriptor.Name);
                LiteralControl literalControl = new LiteralControl();
                literalControl.Text = propertyVal;
                placeHolder.Controls.Add(literalControl);
            }

            protected override System.Web.UI.Control GetChildControlInstance()
            {
                return new PlaceHolder();
            }
        }

        public class PropertyCollectionBinder
        {
            protected DataTable PropertyCollection = new DataTable();

            public PropertyCollectionBinder()
            {
                PropertyCollection.Columns.Add("Name", typeof(string));
                PropertyCollection.Columns.Add("DataSpark", typeof(string));
                PropertyCollection.Columns.Add("LogSpark", typeof(string));
            }

            public void AddProperty(string name, string dataspark, string logspark)
            {
                DataRow newRow = PropertyCollection.Rows.Add();
                newRow["Name"] = name;
                newRow["DataSpark"] = dataspark;
                newRow["LogSpark"] = logspark;
            }

            public void BindGrid(SPGridView grid)
            {
                mySPfield fldPropertyName = new mySPfield();
                fldPropertyName.HeaderText = "Content Database";
                fldPropertyName.DataField = "Name";
                grid.Columns.Add(fldPropertyName);
                mySPfield dataSparkColumn = new mySPfield();
                dataSparkColumn.HeaderText = "Database Size";
                dataSparkColumn.DataField = "Dataspark";
                grid.Columns.Add(dataSparkColumn);
                mySPfield logSparkColumn = new mySPfield();
                logSparkColumn.HeaderText = "Log File Size";
                logSparkColumn.DataField = "Logspark";
                grid.Columns.Add(logSparkColumn);
                grid.DataSource = PropertyCollection.DefaultView;
                grid.DataBind();
            }

        }

    }

}
